agora inbox for [email protected]  
help / color / mirror / Atom feed
[PATCH v2 03/12] Add AutoVacLauncherType to subprocess struct
811+ messages / 2 participants
[nested] [flat]

* [PATCH v2 03/12] Add AutoVacLauncherType to subprocess struct
@ 2020-03-10 22:29  Mike Palmiotto <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Mike Palmiotto @ 2020-03-10 22:29 UTC (permalink / raw)

---
 src/backend/postmaster/autovacuum.c | 66 ++---------------------------
 src/backend/postmaster/postmaster.c | 36 +++++++++-------
 src/backend/postmaster/subprocess.c |  8 ++++
 src/include/postmaster/autovacuum.h |  3 +-
 src/include/postmaster/subprocess.h |  1 +
 5 files changed, 34 insertions(+), 80 deletions(-)

diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index da75e755f0..d0fdb7e5ee 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -95,6 +95,7 @@
 #include "storage/procsignal.h"
 #include "storage/sinvaladt.h"
 #include "storage/smgr.h"
+#include "postmaster/subprocess.h"
 #include "tcop/tcopprot.h"
 #include "utils/fmgroids.h"
 #include "utils/fmgrprotos.h"
@@ -303,11 +304,9 @@ static WorkerInfo MyWorkerInfo = NULL;
 int			AutovacuumLauncherPid = 0;
 
 #ifdef EXEC_BACKEND
-static pid_t avlauncher_forkexec(void);
 static pid_t avworker_forkexec(void);
 #endif
 NON_EXEC_STATIC void AutoVacWorkerMain(int argc, char *argv[]) pg_attribute_noreturn();
-NON_EXEC_STATIC void AutoVacLauncherMain(int argc, char *argv[]) pg_attribute_noreturn();
 
 static Oid	do_start_worker(void);
 static void HandleAutoVacLauncherInterrupts(void);
@@ -353,26 +352,6 @@ static void autovac_refresh_stats(void);
  ********************************************************************/
 
 #ifdef EXEC_BACKEND
-/*
- * forkexec routine for the autovacuum launcher process.
- *
- * Format up the arglist, then fork and exec.
- */
-static pid_t
-avlauncher_forkexec(void)
-{
-	char	   *av[10];
-	int			ac = 0;
-
-	av[ac++] = "postgres";
-	av[ac++] = "--forkavlauncher";
-	av[ac++] = NULL;			/* filled in by postmaster_forkexec */
-	av[ac] = NULL;
-
-	Assert(ac < lengthof(av));
-
-	return postmaster_forkexec(ac, av);
-}
 
 /*
  * We need this set from the outside, before InitProcess is called
@@ -384,50 +363,11 @@ AutovacuumLauncherIAm(void)
 }
 #endif
 
-/*
- * Main entry point for autovacuum launcher process, to be called from the
- * postmaster.
- */
-int
-StartAutoVacLauncher(void)
-{
-	pid_t		AutoVacPID;
-
-#ifdef EXEC_BACKEND
-	switch ((AutoVacPID = avlauncher_forkexec()))
-#else
-	switch ((AutoVacPID = fork_process()))
-#endif
-	{
-		case -1:
-			ereport(LOG,
-					(errmsg("could not fork autovacuum launcher process: %m")));
-			return 0;
-
-#ifndef EXEC_BACKEND
-		case 0:
-			/* in postmaster child ... */
-			InitPostmasterChild();
-
-			/* Close the postmaster's sockets */
-			ClosePostmasterPorts(false);
-
-			AutoVacLauncherMain(0, NULL);
-			break;
-#endif
-		default:
-			return (int) AutoVacPID;
-	}
-
-	/* shouldn't get here */
-	return 0;
-}
-
 /*
  * Main loop for the autovacuum launcher process.
  */
-NON_EXEC_STATIC void
-AutoVacLauncherMain(int argc, char *argv[])
+void
+AutoVacLauncherMain(pg_attribute_unused() int argc, pg_attribute_unused() char *argv[])
 {
 	sigjmp_buf	local_sigjmp_buf;
 
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 4b86aeec2d..2251303589 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -1773,7 +1773,7 @@ ServerLoop(void)
 			(AutoVacuumingActive() || start_autovac_launcher) &&
 			pmState == PM_RUN)
 		{
-			AutoVacPID = StartAutoVacLauncher();
+			AutoVacPID = StartSubprocess(AutoVacuumLauncherType);
 			if (AutoVacPID != 0)
 				start_autovac_launcher = false; /* signal processed */
 		}
@@ -3053,7 +3053,7 @@ reaper(SIGNAL_ARGS)
 			 * situation, some of them may be alive already.
 			 */
 			if (!IsBinaryUpgrade && AutoVacuumingActive() && AutoVacPID == 0)
-				AutoVacPID = StartAutoVacLauncher();
+				AutoVacPID = StartSubprocess(AutoVacuumLauncherType);
 			if (PgArchStartupAllowed() && PgArchPID == 0)
 				PgArchPID = pgarch_start();
 			if (PgStatPID == 0)
@@ -5041,19 +5041,6 @@ SubPostmasterMain(int argc, char *argv[])
 		/* And run the backend */
 		BackendRun(&port);		/* does not return */
 	}
-	if (strcmp(argv[1], "--forkavlauncher") == 0)
-	{
-		/* Restore basic shared memory pointers */
-		InitShmemAccess(UsedShmemSegAddr);
-
-		/* Need a PGPROC to run CreateSharedMemoryAndSemaphores */
-		InitProcess();
-
-		/* Attach process to shared data structures */
-		CreateSharedMemoryAndSemaphores();
-
-		AutoVacLauncherMain(argc - 2, argv + 2);	/* does not return */
-	}
 	if (strcmp(argv[1], "--forkavworker") == 0)
 	{
 		/* Restore basic shared memory pointers */
@@ -5121,6 +5108,19 @@ SubPostmasterMain(int argc, char *argv[])
 
 		AuxiliaryProcessMain(argc - 2, argv + 2);	/* does not return */
 	}
+	else
+	{
+		/* Restore basic shared memory pointers */
+		InitShmemAccess(UsedShmemSegAddr);
+
+		/* Need a PGPROC to run CreateSharedMemoryAndSemaphores */
+		InitProcess();
+
+		/* Attach process to shared data structures */
+		CreateSharedMemoryAndSemaphores();
+
+		MySubprocess->entrypoint(argc - 2, argv + 2);
+	}
 
 	abort();					/* shouldn't get here */
 }
@@ -5488,7 +5488,11 @@ StartSubprocess(SubprocessType type)
 		MemoryContextDelete(PostmasterContext);
 		PostmasterContext = NULL;
 
-		AuxiliaryProcessMain(argc, argv);
+		if (MySubprocess->needs_aux_proc)
+			AuxiliaryProcessMain(argc, argv);
+		else
+			MySubprocess->entrypoint(argc, argv);
+
 		ExitPostmaster(0);
 	}
 #endif							/* EXEC_BACKEND */
diff --git a/src/backend/postmaster/subprocess.c b/src/backend/postmaster/subprocess.c
index 7e96678dfb..9aa60cc93e 100644
--- a/src/backend/postmaster/subprocess.c
+++ b/src/backend/postmaster/subprocess.c
@@ -12,6 +12,7 @@
  */
 #include "postgres.h"
 #include "bootstrap/bootstrap.h"
+#include "postmaster/autovacuum.h"
 #include "postmaster/bgwriter.h"
 #include "postmaster/postmaster.h"
 #include "postmaster/startup.h"
@@ -71,6 +72,13 @@ static PgSubprocess process_types[] = {
 		.needs_aux_proc = true,
 		.entrypoint = WalReceiverMain,
 		.fork_failure = NULL
+	},
+	{
+		.name = "avlauncher",
+		.desc = "autovacuum launcher",
+		.needs_aux_proc = false,
+		.entrypoint = AutoVacLauncherMain,
+		.fork_failure = NULL
 	}
 };
 
diff --git a/src/include/postmaster/autovacuum.h b/src/include/postmaster/autovacuum.h
index d40ed55531..08050cd81c 100644
--- a/src/include/postmaster/autovacuum.h
+++ b/src/include/postmaster/autovacuum.h
@@ -58,6 +58,8 @@ extern void autovac_init(void);
 extern int	StartAutoVacLauncher(void);
 extern int	StartAutoVacWorker(void);
 
+extern void AutoVacLauncherMain(int argc, char *argv[]);
+
 /* called from postmaster when a worker could not be forked */
 extern void AutoVacWorkerFailed(void);
 
@@ -65,7 +67,6 @@ extern void AutoVacWorkerFailed(void);
 extern void AutoVacuumUpdateDelay(void);
 
 #ifdef EXEC_BACKEND
-extern void AutoVacLauncherMain(int argc, char *argv[]) pg_attribute_noreturn();
 extern void AutoVacWorkerMain(int argc, char *argv[]) pg_attribute_noreturn();
 extern void AutovacuumWorkerIAm(void);
 extern void AutovacuumLauncherIAm(void);
diff --git a/src/include/postmaster/subprocess.h b/src/include/postmaster/subprocess.h
index 33f6a7ab04..9e3c743333 100644
--- a/src/include/postmaster/subprocess.h
+++ b/src/include/postmaster/subprocess.h
@@ -23,6 +23,7 @@ typedef enum
 	CheckpointerType,
 	WalWriterType,
 	WalReceiverType,	/* end of Auxiliary Process Forks */
+	AutoVacuumLauncherType,
 
 	NUMSUBPROCESSTYPES			/* Must be last! */
 } SubprocessType;
-- 
2.17.0


--FcSpk3Icpd/Pbul4
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
 filename="v2-0004-Add-AutoVacuumWorkerType-to-subprocess-struct.patch"



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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








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

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

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

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

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


--nextPart6784952.tM3a2QDmDi--

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

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

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

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28  Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 811+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 811+ messages in thread


end of thread, other threads:[~2025-09-04 16:28 UTC | newest]

Thread overview: 811+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2020-03-10 22:29 [PATCH v2 03/12] Add AutoVacLauncherType to subprocess struct Mike Palmiotto <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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]>

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox